package com.flycms.modules.shiro;

import com.flycms.modules.user.entity.Admin;
import com.flycms.modules.user.entity.LoginUser;
import com.flycms.modules.user.service.*;
import com.flycms.modules.user.entity.User;
import com.flycms.modules.user.service.impl.UserServiceImpl;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.HashSet;
import java.util.Set;

/**
 * Biz-Boot, All rights reserved
 * 版权：企业之家网 -- 企业建站管理系统<br/>
 * 开发公司：97560.com<br/>
 *
 * @author 孙开飞
 * @version 1.0 <br/>
 * @email 79678111@qq.com
 * @Date: 23:18 2019/8/17
 */
@Component
public class MyShiroRealm extends AuthorizingRealm {

    private Logger log = LoggerFactory.getLogger(MyShiroRealm.class);
    @Autowired
    private AdminService adminService;
    @Autowired
    private AdminRoleService adminRoleService;
    @Autowired
    private AdminMenuService adminMenuService;
    @Autowired
    private UserServiceImpl userService;
    @Autowired
    private UserRoleService userRoleService;
    @Autowired
    private UserMenuService menuService;

    // 用户权限配置
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        if (ShiroUtils.getLoginUser().getLoginType() == 1) {
            // 角色列表
            Set<String> roles = adminRoleService.selectRoleKeys(ShiroUtils.getLoginUser().getId());
            // 功能列表
            Set<String> menus = new HashSet<String>();
            SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

            boolean contains = roles.contains("admin");
            // 管理员拥有所有权限
            if (contains) {
                info.addRole("admin");
                info.addStringPermission("*:*:*");
            } else {
                menus = adminMenuService.selectPermsByUserId(ShiroUtils.getLoginUser().getId());
                // 角色加入AuthorizationInfo认证对象
                info.setRoles(roles);
                // 权限加入AuthorizationInfo认证对象
                info.setStringPermissions(menus);
            }
            return info;
        } else {
            // 角色列表
            Set<String> roles = userRoleService.selectRoleKeys(ShiroUtils.getLoginUser().getId());
            // 功能列表
            SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
            //所有菜单
            Set<String> menus = menuService.selectPermsByUserId(ShiroUtils.getLoginUser().getId());
            // 角色加入AuthorizationInfo认证对象
            info.setRoles(roles);
            // 权限加入AuthorizationInfo认证对象
            info.setStringPermissions(menus);
            return info;
        }
    }

    /**
     * 执行认证逻辑
     *
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        LoginUser loginUser = new LoginUser();
        if (authenticationToken instanceof UserToken) //普通用户的认证逻辑
        {
            UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
            String username = token.getUsername();
            log.info("用户：{} 正在登录...", username);
            User user = userService.findByUsername(username);
            if (user == null) throw new UnknownAccountException();
            loginUser.setId(user.getId());
            loginUser.setUserName(user.getUserName());
            loginUser.setPassword(user.getPassword());
            loginUser.setLoginType(0);
            return new SimpleAuthenticationInfo(loginUser, loginUser.getPassword(), getName());
        } else if (authenticationToken instanceof AdminToken) //管理员的认证逻辑
        {
            UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
            String username = token.getUsername();
            log.info("管理员：{} 正在登录...", username);
            Admin admin = adminService.findByUsername(username);
            if (admin == null) throw new UnknownAccountException();
            loginUser.setId(admin.getId());
            loginUser.setUserName(admin.getUserName());
            loginUser.setPassword(admin.getPassword());
            loginUser.setLoginType(1);
            return new SimpleAuthenticationInfo(loginUser, loginUser.getPassword(), getName());
        } else {
            return null;
        }
    }
}
